package org.xbill.DNS;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

public class Master
{
  private int currentDClass;
  private long currentTTL;
  private int currentType;
  private long defaultTTL;
  private File file;
  private Generator generator;
  private List generators;
  private Master included;
  private Record last;
  private boolean needSOATTL;
  private boolean noExpandGenerate;
  private Name origin;
  private Tokenizer st;

  Master(File paramFile, Name paramName, long paramLong)
    throws IOException
  {
    this.last = null;
    this.included = null;
    if ((paramName != null) && (!(paramName.isAbsolute())))
      throw new RelativeNameException(paramName);
    this.file = paramFile;
    this.st = new Tokenizer(paramFile);
    this.origin = paramName;
    this.defaultTTL = paramLong;
  }

  public Master(InputStream paramInputStream)
  {
    this(paramInputStream, null, -1L);
  }

  public Master(InputStream paramInputStream, Name paramName)
  {
    this(paramInputStream, paramName, -1L);
  }

  public Master(InputStream paramInputStream, Name paramName, long paramLong)
  {
    this.last = null;
    this.included = null;
    if ((paramName != null) && (!(paramName.isAbsolute())))
      throw new RelativeNameException(paramName);
    this.st = new Tokenizer(paramInputStream);
    this.origin = paramName;
    this.defaultTTL = paramLong;
  }

  public Master(String paramString)
    throws IOException
  {
    this(new File(paramString), null, -1L);
  }

  public Master(String paramString, Name paramName)
    throws IOException
  {
    this(new File(paramString), paramName, -1L);
  }

  public Master(String paramString, Name paramName, long paramLong)
    throws IOException
  {
    this(new File(paramString), paramName, paramLong);
  }

  private void endGenerate()
    throws IOException
  {
    this.st.getEOL();
    this.generator = null;
  }

  private Record nextGenerated()
    throws IOException
  {
    Record localRecord;
    try
    {
      localRecord = this.generator.nextRecord();
      return localRecord;
    }
    catch (Tokenizer.TokenizerException localTokenizerException)
    {
      throw this.st.exception("Parsing $GENERATE: " + localTokenizerException.getBaseMessage());
    }
    catch (TextParseException localTextParseException)
    {
      throw this.st.exception("Parsing $GENERATE: " + localTextParseException.getMessage());
    }
  }

  private Name parseName(String paramString, Name paramName)
    throws TextParseException
  {
    Name localName;
    try
    {
      localName = Name.fromString(paramString, paramName);
      return localName;
    }
    catch (TextParseException localTextParseException)
    {
      throw this.st.exception(localTextParseException.getMessage());
    }
  }

  private void parseTTLClassAndType()
    throws IOException
  {
    int i = 0;
    Object localObject = this.st.getString();
    int j = DClass.value((String)localObject);
    this.currentDClass = j;
    if (j >= 0)
    {
      localObject = this.st.getString();
      i = 1;
    }
    this.currentTTL = -1L;
    try
    {
      this.currentTTL = TTL.parseTTL((String)localObject);
      String str = this.st.getString();
      localObject = str;
      if (i == 0)
      {
        int l = DClass.value((String)localObject);
        this.currentDClass = l;
        if (l < 0)
          break label179;
        localObject = this.st.getString();
      }
      int k = Type.value((String)localObject);
      this.currentType = k;
      label179: if (k < 0)
        throw this.st.exception("Invalid type '" + ((String)localObject) + "'");
    }
    catch (NumberFormatException localNumberFormatException)
    {
      while (true)
      {
        while (true)
        {
          do
            while (this.defaultTTL >= 0L)
              this.currentTTL = this.defaultTTL;
          while (this.last == null);
          this.currentTTL = this.last.getTTL();
        }
        this.currentDClass = 1;
      }
      if (this.currentTTL < 0L)
      {
        if (this.currentType != 6)
          throw this.st.exception("missing TTL");
        this.needSOATTL = true;
        this.currentTTL = 0L;
      }
    }
  }

  private long parseUInt32(String paramString)
  {
    long l1;
    if (!(Character.isDigit(paramString.charAt(0))))
    {
      l1 = -1L;
      return l1;
    }
    try
    {
      long l2;
      while (true)
      {
        l2 = Long.parseLong(paramString);
        if ((l2 >= 0L) && (l2 <= -1L))
          break;
        l1 = -1L;
      }
      l1 = l2;
    }
    catch (NumberFormatException localNumberFormatException)
    {
      l1 = -1L;
    }
  }

  private void startGenerate()
    throws IOException
  {
    long l3;
    String str1 = this.st.getIdentifier();
    int i = str1.indexOf("-");
    if (i < 0)
      throw this.st.exception("Invalid $GENERATE range specifier: " + str1);
    String str2 = str1.substring(0, i);
    String str3 = str1.substring(i + 1);
    String str4 = null;
    int j = str3.indexOf("/");
    if (j >= 0)
    {
      int k = j + 1;
      str4 = str3.substring(k);
      str3 = str3.substring(0, j);
    }
    long l1 = parseUInt32(str2);
    long l2 = parseUInt32(str3);
    if (str4 != null)
      l3 = parseUInt32(str4);
    while ((l1 < 0L) || (l2 < 0L) || (l1 > l2) || (l3 <= 0L))
    {
      throw this.st.exception("Invalid $GENERATE range specifier: " + str1);
      l3 = 1L;
    }
    String str5 = this.st.getIdentifier();
    parseTTLClassAndType();
    if (!(Generator.supportedType(this.currentType)))
      throw this.st.exception("$GENERATE does not support " + Type.string(this.currentType) + " records");
    String str6 = this.st.getIdentifier();
    this.st.getEOL();
    this.st.unget();
    this.generator = new Generator(l1, l2, l3, str5, this.currentType, this.currentDClass, this.currentTTL, str6, this.origin);
    if (this.generators == null)
      this.generators = new ArrayList(1);
    this.generators.add(this.generator);
  }

  public Record _nextRecord()
    throws IOException
  {
    label59: Tokenizer.Token localToken1;
    Object localObject;
    if (this.included != null)
    {
      Record localRecord2 = this.included.nextRecord();
      if (localRecord2 != null)
        localObject = localRecord2;
    }
    while (true)
    {
      Tokenizer.Token localToken3;
      while (true)
      {
        return localObject;
        this.included = null;
        if (this.generator == null)
          break label59;
        Record localRecord1 = nextGenerated();
        if (localRecord1 == null)
          break;
        localObject = localRecord1;
      }
      endGenerate();
      do
      {
        localToken1 = this.st.get(true, false);
        if (localToken1.type != 2)
          break label220;
        localToken3 = this.st.get();
      }
      while (localToken3.type == 1);
      if (localToken3.type != 0)
        break;
      localObject = null;
    }
    this.st.unget();
    if (this.last == null)
      throw this.st.exception("no owner");
    Name localName1 = this.last.getName();
    while (true)
    {
      do
      {
        label220: String str1;
        while (true)
        {
          while (true)
          {
            while (true)
            {
              while (true)
              {
                while (true)
                {
                  do
                    while (true)
                    {
                      parseTTLClassAndType();
                      this.last = Record.fromString(localName1, this.currentType, this.currentDClass, this.currentTTL, this.st, this.origin);
                      if (this.needSOATTL)
                      {
                        long l = ((SOARecord)this.last).getMinimum();
                        this.last.setTTL(l);
                        this.defaultTTL = l;
                        this.needSOATTL = false;
                      }
                      localObject = this.last;
                    }
                  while (localToken1.type == 1);
                  if (localToken1.type != 0)
                    break;
                  localObject = null;
                }
                if (localToken1.value.charAt(0) != '$')
                  break label537;
                str1 = localToken1.value;
                if (!(str1.equalsIgnoreCase("$ORIGIN")))
                  break;
                this.origin = this.st.getName(Name.root);
                this.st.getEOL();
              }
              if (!(str1.equalsIgnoreCase("$TTL")))
                break;
              this.defaultTTL = this.st.getTTL();
              this.st.getEOL();
            }
            if (str1.equalsIgnoreCase("$INCLUDE"))
            {
              File localFile;
              String str2 = this.st.getString();
              if (this.file != null)
                localFile = new File(this.file.getParent(), str2);
              while (true)
              {
                while (true)
                {
                  Name localName2 = this.origin;
                  Tokenizer.Token localToken2 = this.st.get();
                  if (localToken2.isString())
                  {
                    localName2 = parseName(localToken2.value, Name.root);
                    this.st.getEOL();
                  }
                  this.included = new Master(localFile, localName2, this.defaultTTL);
                  localObject = nextRecord();
                }
                localFile = new File(str2);
              }
            }
            if (!(str1.equalsIgnoreCase("$GENERATE")))
              break label511;
            if (this.generator != null)
              throw new IllegalStateException("cannot nest $GENERATE");
            startGenerate();
            if (!(this.noExpandGenerate))
              break;
            endGenerate();
          }
          localObject = nextGenerated();
        }
        label511: throw this.st.exception("Invalid directive: " + str1);
        label537: localName1 = parseName(localToken1.value, this.origin);
      }
      while ((this.last == null) || (!(localName1.equals(this.last.getName()))));
      localName1 = this.last.getName();
    }
  }

  public void expandGenerate(boolean paramBoolean)
  {
    int i;
    if (paramBoolean)
      i = 0;
    while (true)
    {
      this.noExpandGenerate = i;
      return;
      i = 1;
    }
  }

  protected void finalize()
  {
    this.st.close();
  }

  public Iterator generators()
  {
    Iterator localIterator;
    if (this.generators != null)
      localIterator = Collections.unmodifiableList(this.generators).iterator();
    while (true)
    {
      return localIterator;
      localIterator = Collections.EMPTY_LIST.iterator();
    }
  }

  public Record nextRecord()
    throws IOException
  {
    Record localRecord;
    try
    {
      localRecord = _nextRecord();
      return localRecord;
    }
    finally
    {
      if (0 == 0)
        this.st.close();
    }
  }
}